Gradle Kotlin DSL.md

Gradle Kotlin DSL

什么是 DSL?

DSL(domain specific language),即领域专用语言:专门解决某一特定问题的计算机语言,比如大家耳熟能详的 SQL 和正则表达式。

Gradle 的 Kotlin DSL 使用要求和优缺点

Gradle 的 Kotlin DSL 提供了传统 Groovy DSL 的替代语法,并在受支持的 IDE 中提供了增强的编辑体验,并具有出色的内容辅助,重构,文档等功能。

  1. 使用要求
    • 尽可能的保证 Gradle 和 Android 版本为最新版本
    • JDK 版本至少是 8 或者以上
  2. 优点
    • Kotlin 是 Android 官方推荐语言,使用 Kotlin 构建 Gradle 脚本有利于整个项目开发语言的统一。
    • Kotlin DSL 支持跳转到源码。
    • Kotlin DSL 在编译时检查错误。
    • Kotlin DSL 支持代码自动补全和语法高亮。
  3. 缺点
    • 编译速度有所欠缺。

从 Groovy 迁移到 Kotlin DSL 的步骤

  1. 语法的区分

    • Groovy 字符串可以用单引号 ’string’ 或双引号引起来 “string”,而 Kotlin 需要双引号 “string”。
    • Groovy 允许在调用函数时省略括号,而 Kotlin 始终需要括号。
    • Gradle Groovy DSL 允许 = 在分配属性时省略赋值运算符,而 Kotlin 始终需要赋值运算符。
  2. 需要改造的文件

    • settings.gradle
    • project 目录下的 build.gradle
    • app 目录下的 build.gradle
  3. 步骤(按照上述罗列的顺序依次进行)

    • settings.gradle (Gradle Groovy DSL 允许 = 在分配属性时省略赋值运算符,而 Kotlin 始终需要赋值运算符。)

      修改文件名称为 settings.gradle.kts,将原来的代码

      1
      2
      include ':app'
      rootProject.name = "ProjectName"
替换为以下代码

1
2
include(":app")
rootProject.name = "ProjectName"
  • project / build.gradle

    同样,第一步是修改文件名称,把build.gradle 重命名为 build.gradle.kts,先罗列出原来的代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    buildscript {
    val kotlin_version = "1.3.61" // #1
    repositories {
    google()
    jcenter()
    }
    dependencies {
    classpath("com.android.tools.build:gradle:4.0.0-beta01") // #2
    classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version")

    // NOTE: Do not place your application dependencies here; they belong
    // in the individual module build.gradle files
    }
    }

    allprojects {
    repositories {
    google()
    jcenter()
    }
    }

    tasks.register("clean", Delete::class) { // #3
    delete(rootProject.buildDir)
    }
将上面代码标注的三个地方替换成以下代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
buildscript {
val kotlinVersion = "1.3.72"
repositories {
google()
jcenter()
}
dependencies {
classpath("com.android.tools.build:gradle:4.0.0")
classpath(kotlin("gradle-plugin", kotlinVersion))
}
}

allprojects {
repositories {
google()
jcenter()

maven {
setUrl("https://jitpack.io")
}
}
}

tasks {
val clean by registering(Delete::class) {
delete(buildDir)
}
}
  • app / build.gradle

    同样,先修改名称,将 build.gradle重命名为 build.gardle.kts,该文件修改的较多,直接展示已完成的代码,然后点击 Sync now,同步构建以下代码。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    plugins {  // #1
    id("com.android.application")
    kotlin("android")
    kotlin("android.extensions")
    }

    android {
    compileSdkVersion(29) // #2
    buildToolsVersion("29.0.3")

    defaultConfig {
    applicationId = "com.example.projectname"
    minSdkVersion(21)
    targetSdkVersion(29)
    versionCode = 1
    versionName = "1.0"
    }

    buildTypes {
    getByName("release") { // #3
    isMinifyEnabled = false
    proguardFiles (getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
    }
    }
    }

    dependencies {
    implementation(
    fileTree( // #4
    mapOf("dir" to "libs", "include" to listOf("*.jar"))
    )
    )
    implementation (kotlin(
    "stdlib-jdk7",
    org.jetbrains.kotlin.config.KotlinCompilerVersion.VERSION
    ))
    implementation("androidx.core:core-ktx:1.2.0")
    implementation("androidx.appcompat:appcompat:1.1.0")
    implementation("androidx.constraintlayout:constraintlayout:1.1.3")
    testImplementation("junit:junit:4.12")
    androidTestImplementation("androidx.test.ext:junit:1.1.1")
    androidTestImplementation("androidx.test.espresso:espresso-core:3.2.0")
    }
看到以上代码,不知你是否存在这样的想法?(所有的版本号、依赖库等直接写在 build.gradle.kts 文件中,能不能有一个文件统一进行管理呢??)答案当然是可以的(官方提供的解决方案:**buildSrc**),**最后再简单说一下 buildSrc 这个文件夹的作用:管理整个项目的依赖。**

创建 buildSrc

  1. 在项目的根目录下创建 buildSrc 文件夹,然后分别创建 src/main/kotlin 和 build.gradle.kts 文件就可以。

    1
    2
    3
    4
    5
    6
    buildSrc
    ├── build.gradle.kts
    └── src
    └── main
    └── kotlin
    └── AndroidConfig
  2. 在 src/main/kotlin 目录下创建 AndroidConfig 文件,分别将版本信息罗列出来。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    object AndroidConfig {
    const val compileSdkVersion = 29
    const val buildToolsVersion = "29.0.3"
    const val minSdkVersion = 21
    const val targetSdkVersion = 29
    const val versionCode = 1
    const val versionName = "1.0.0"

    const val applicationID = "com.example.projectname"

    const val testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
    }

    interface BuildType {
    companion object {
    const val Release = "release"
    const val Debug = "debug"
    }

    val isMinifyEnabled: Boolean
    }

    object BuildTypeDebug : BuildType {
    override val isMinifyEnabled = false
    }

    object BuildTypeRelease : BuildType {
    override val isMinifyEnabled = false
    }

    object TestOptions {
    const val isReturnDefaultValues = true
    }
  1. 最后在 app/build.gradle.kts 文件中引用即可。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    plugins {
    id("com.android.application")
    kotlin("android")
    kotlin("android.extensions")
    }

    android {
    compileSdkVersion(AndroidConfig.compileSdkVersion)
    buildToolsVersion(AndroidConfig.buildToolsVersion)

    defaultConfig {
    applicationId = AndroidConfig.applicationID

    minSdkVersion(AndroidConfig.minSdkVersion)
    targetSdkVersion(AndroidConfig.targetSdkVersion)
    versionCode = AndroidConfig.versionCode
    versionName = AndroidConfig.versionName
    }

    dependencies {
    implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar", "*.aar")))) // ## 重点
    implementation(LibraryDependency.KOTLIN)
    implementation(LibraryDependency.COREKTX)
    testImplementation(LibraryDependency.JUNIT)
    androidTestImplementation(LibraryDependency.EXTJUNIT)
    }

注:贴出的代码不完整,简单贴一下。

  1. 完善一下 buildSrc 下的 build.gradle.kts 文件

    1
    2
    3
    4
    5
    6
    7
    plugins {
    `kotlin-dsl`
    }

    repositories {
    jcenter()
    }

参考

Gradle 官方文档

Gradle Kotlin DSL , 你知道它吗?

buildSrc

0%